using AutoMapper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Mvc;
using ShopPowerTemplate.Entities;
using ShopPowerTemplate.IoC;
using ShopPowerTemplate.Presentation.Mvc.Extensions;
using ShopPowerTemplate.Presentation.Mvc.Models;
using ShopPowerTemplate.Presentation.Mvc.ViewModels;
using ShopPowerTemplate.Services;

namespace ShopPowerTemplate.Presentation.Mvc.Controllers
{
	public partial class CategoryControllerBase : BaseController
	{
		#region Members

        protected ICategoryService _categoryService;
        protected ISubcategoryService _subcategoryService;

        #endregion

        #region Constructors

        public CategoryControllerBase(ICategoryService categoryService, ISubcategoryService subcategoryService)
        {
            _categoryService = categoryService;
            _subcategoryService = subcategoryService;
        }	

        #endregion

		#region Index

		// **************************************
        // URL: /Category
        // **************************************
		public virtual ActionResult Index()
		{
			IndexCategoryViewModel viewModel = new IndexCategoryViewModel();
			ViewBag.PageIndex = this.GetPageIndex();
            ViewBag.PageSize = this.GetPageSize();
			ViewBag.SearchValue = this.GetSearchValue();
		
			return View(viewModel);
		}

		[AcceptVerbs(HttpVerbs.Post)]
        public virtual ActionResult Load(string sidx, string sord, int page, int rows, string search, int mode = 1)
        {
            string searchValue = this.GetSearchValue();
            OrderBy orderBy = this.GetOrderBy();
            int pageIndex = this.GetPageIndex();
            int pageSize = this.GetPageSize();

            if (mode == (int)JQGridActionEnum.DefaultLoad)
            {                
                pageSize = (pageIndex + 1) * pageSize;
                pageIndex = 0;
            }
            else if (mode == (int)JQGridActionEnum.ShowMoreResults)
            {
                pageIndex = page;
                this.SetPageIndex(pageIndex);
            }
            else if (mode == (int)JQGridActionEnum.CustomSearch)
            {
                searchValue = search;
                this.SetSearchValue(searchValue);
                pageIndex = 0;
                this.SetPageIndex(pageIndex);
                orderBy = new OrderBy("", true);
                this.SetOrderBy(orderBy);
            }

            if (!string.IsNullOrEmpty(sidx)) // Sort request
            {
                orderBy = new OrderBy(sidx, sord == "asc");
                this.SetOrderBy(orderBy);
            }

            List<Category> searchList = _categoryService.Search(searchValue, orderBy.Property, orderBy.Ascending, pageIndex, pageSize);
            int count = _categoryService.SearchCount(searchValue);
            
			if (!string.IsNullOrEmpty(sidx)) // Sort request
            {
                pageIndex = this.GetPageIndex();
            }

            var data = new
            {
                total = Math.Ceiling((float)count/(float)pageSize),        // Total pages
                page = pageIndex,      // Current page
                records = count,  // Total records
                rows = from category in searchList     // Row data
                       select new
                       {
                           id = category.Id,                
                           cell = new string[] {
						   
                                category.Name,
								category.Description
								
                           }
                       }
            };

            return Json(data);
        }

		[AcceptVerbs(HttpVerbs.Post)]
        public virtual ActionResult Delete(int id)
        {
            try
            {
                _categoryService.Remove(id);
            }
            catch (RemoveException ex)
            {
                Response.StatusCode = 500;
                return Content(ex.Message);
            }
            return Content(string.Empty);
        }
		
		public virtual FileContentResult Report()
        {
            IList<Category> _categoryList = _categoryService.Search(this.GetSearchValue());            
            StringBuilder strBuilder = new StringBuilder();

            // columns
            strBuilder.AppendLine("Name;Description");

            // rows
            foreach (Category category in _categoryList)
            {
                List<string> rowData = new List<string>() { category.Name, category.Description };
                strBuilder.AppendLine(rowData.Aggregate((x, y) => x + ";" + y));
            }

			// encode report content
            System.IO.MemoryStream content = new System.IO.MemoryStream();
            using (System.IO.StreamWriter writer = new System.IO.StreamWriter(content, UTF8Encoding.UTF8))
                writer.Write(strBuilder.ToString());

            return File(content.ToArray(), "text/csv", "Category.csv");
        }
		

		#endregion

		#region Create

		// *******************************************
        // URL: /Category/Create
        // *******************************************
		[AcceptVerbs(HttpVerbs.Get)]
        public virtual ActionResult Create()
        {
            Category category = new Category();
            CreateCategoryViewModel viewModel = Mapper.Map<Category, CreateCategoryViewModel>(category);
            
			return View(viewModel);
        }

		[AcceptVerbs(HttpVerbs.Post)]
        public virtual ActionResult Create(CreateCategoryViewModel categoryModel)
        {
            if (ModelState.IsValid)
            {
                Category category = new Category();
                AutoMapper.Mapper.Map<CreateCategoryViewModel, Category>(categoryModel, category);
 
                foreach (string inputTagName in Request.Files)
                {
                    HttpPostedFileBase file = Request.Files[inputTagName];

                    if (inputTagName == "Image" && file.ContentLength > 0)
                    {
                        category.Image = Helpers.ZipUtil.Zip(file);
                    }
				}

				_categoryService.Add(category);

                return RedirectToAction("Edit", new { id = category.Id});
            }
            else
            {

                return View(categoryModel);
            }
		}
		

		#endregion

		#region Edit

		// *******************************************
        // URL: /Category/Edit/id
        // *******************************************
		[AcceptVerbs(HttpVerbs.Get)]
        public virtual ActionResult Edit(int id)
        {
            Category category = _categoryService.Find(id);
            EditCategoryViewModel viewModel = Mapper.Map<Category, EditCategoryViewModel>(category);
            
			return View(viewModel);
        }

		[AcceptVerbs(HttpVerbs.Post)]
        public virtual ActionResult Edit(EditCategoryViewModel categoryModel)
        {
            if (ModelState.IsValid)
            {
                Category category = _categoryService.Find(categoryModel.Id);
                AutoMapper.Mapper.Map<EditCategoryViewModel, Category>(categoryModel, category);
                
                foreach (string inputTagName in Request.Files)
                {
                    HttpPostedFileBase file = Request.Files[inputTagName];

                    if (inputTagName == "Image" && file.ContentLength > 0)
                    {
                        category.Image = Helpers.ZipUtil.Zip(file);
                    }
				}
				_categoryService.Change(category);

                return RedirectToAction("Index");
            }
            else
            {

                return View(categoryModel);
            }
		}
		[AcceptVerbs(HttpVerbs.Post)]
        public virtual ActionResult LoadSubcategories(string sidx, string sord, int page, int rows, string search, int mode = 1, int masterId = 0)
        {
			Category currentCategory = _categoryService.Find(masterId);
            List<Subcategory> list = currentCategory.Subcategories.ToList();
			int count = list.Count();

			var data = new
            {
                total = 1,        // Total pages
                page = 1,      // Current page
                records = count,  // Total records
                rows = from subcategory in list     // Row data
                       select new
                       {
                           id = subcategory.Id,                
                           cell = new string[] {
                                subcategory.Name,
								subcategory.Description
                           }
                       }
            };

            // Return elements
            return Json(data);
        }

		public virtual ActionResult AddSubcategories(int masterId = 0)
        {
            PopUpSubcategoryViewModel viewModel = new PopUpSubcategoryViewModel();

			viewModel.CategoryId = masterId;
			ViewBag.MasterProperty = "Category";
            ViewBag.Name = "AddSubcategories";

            return PartialView("~/Views/Subcategory/PopUp.cshtml", viewModel);
        }
		
		[AcceptVerbs(HttpVerbs.Post)]
        public virtual ActionResult AddSubcategories(PopUpSubcategoryViewModel subcategoryModel)
        {
            if (ModelState.IsValid)
            {
                Subcategory subcategories = new Subcategory();
                AutoMapper.Mapper.Map<PopUpSubcategoryViewModel, Subcategory>(subcategoryModel, subcategories);

				Category category = _categoryService.Find(subcategories.Category.Id);
				_categoryService.AddSubcategories(category, subcategories);
                
				Response.StatusCode = 200;
                return Content("OK", "text/plain");
            }
            else
            {
				ViewBag.MasterProperty = "Category";
            	ViewBag.Name = "AddSubcategories";


				return PartialView("~/Views/Subcategory/PopUp.cshtml", subcategoryModel);
            }
        }	
		
		public virtual ActionResult EditSubcategories(int id, int masterId = 0)
        {
			Subcategory subcategory = _subcategoryService.Find(id);
            PopUpSubcategoryViewModel viewModel = Mapper.Map<Subcategory, PopUpSubcategoryViewModel>(subcategory);

			List<Category> allCategory = _categoryService.FindAll();
			viewModel.CategoryId = masterId;
			ViewBag.MasterProperty = "Category";
            ViewBag.Name = "EditSubcategories";

            return PartialView("~/Views/Subcategory/PopUp.cshtml", viewModel);
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public virtual ActionResult EditSubcategories(PopUpSubcategoryViewModel subcategoryModel)
        {
            if (ModelState.IsValid)
            {
                Subcategory subcategory = _subcategoryService.Find(subcategoryModel.Id);
                AutoMapper.Mapper.Map<PopUpSubcategoryViewModel, Subcategory>(subcategoryModel, subcategory);

                _subcategoryService.Change(subcategory);

                Response.StatusCode = 200;
                return Content("OK", "text/plain");
            }
            else
            {
				List<Category> allCategory = _categoryService.FindAll();
				subcategoryModel.CategoryList = allCategory;
				ViewBag.MasterProperty = "Category";

                return PartialView("~/Views/Subcategory/PopUp.cshtml", subcategoryModel);
            }
        }
		
		[AcceptVerbs(HttpVerbs.Post)]
        public virtual void DeleteSubcategories(int id, int masterId = 0)
        {
			Subcategory subcategory = _subcategoryService.Find(id);
			Category currentCategory = _categoryService.Find(masterId);

            _categoryService.RemoveSubcategories(currentCategory, subcategory);
        }
			
		public virtual FileContentResult ReportSubcategories(int masterId = 0)
        {
			Category currentCategory = _categoryService.Find(masterId);
            IList<Subcategory> _subcategoriesList = currentCategory.Subcategories.ToList();          
            StringBuilder strBuilder = new StringBuilder();

            // columns
            strBuilder.AppendLine("Name;Description");

            // rows
            foreach (Subcategory subcategory in _subcategoriesList)
            {
                List<string> rowData = new List<string>() { subcategory.Name, subcategory.Description };
                strBuilder.AppendLine(rowData.Aggregate((x, y) => x + ";" + y));
            }

			// encode report content
            System.IO.MemoryStream content = new System.IO.MemoryStream();
            using (System.IO.StreamWriter writer = new System.IO.StreamWriter(content, UTF8Encoding.UTF8))
                writer.Write(strBuilder.ToString());

            return File(content.ToArray(), "text/csv", "Subcategories.csv");
        }
		

		#endregion

		#region Details

		// *******************************************
        // URL: /Category/Details/id
        // *******************************************
		[AcceptVerbs(HttpVerbs.Get)]
        public virtual ActionResult Details(int id)
        {
            Category category = _categoryService.Find(id);
            DetailsCategoryViewModel viewModel = Mapper.Map<Category, DetailsCategoryViewModel>(category);
            
			return View(viewModel);
        }
		

		#endregion

		#region Downloads

		public virtual ActionResult DownloadBinary(int id, string p)
		{
			Category category = _categoryService.Find(id);
			byte[] contents = null;
			string filename = string.Empty;
			
	
			if(p == "Image")
			{
				contents = Helpers.ZipUtil.Unzip(category.Image, out filename);
			}
			

			return File(contents, Helpers.FileHelper.GetMimeType(filename), filename);
		}

		#endregion
	}
}
